﻿#define _CRT_SECURE_NO_WARNINGS 1
//#include <iostream>
//using namespace std;
////不能拷贝
//class ProhibitCopy
//{
//public:
//	ProhibitCopy()
//	{}
//private:
//	ProhibitCopy(const ProhibitCopy& c);
//	ProhibitCopy& operator=(const ProhibitCopy& c);
//};
//int main()
//{
//	ProhibitCopy p1;
//	//ProhibitCopy p2= p1;
//	ProhibitCopy p3;
//	//p3 = p1;
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
////不能拷贝
//class ProhibitCopy
//{
//public:
//	ProhibitCopy()
//	{}
//	ProhibitCopy(const ProhibitCopy& c) = delete;
//	ProhibitCopy& operator=(const ProhibitCopy& c)=delete;
//};
//int main()
//{
//	ProhibitCopy p1;
//	//ProhibitCopy p2= p1;
//	ProhibitCopy p3;
//	//p3 = p1;
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
////只能在堆上创建对象
//class OnlyHeap
//{
//public:
//	static OnlyHeap* CreateObject()
//	{
//		return new OnlyHeap;
//	}
//
//private:
//	OnlyHeap()
//	{}
//	//OnlyHeap(const OnlyHeap&) = delete;
//	OnlyHeap& operator=(const OnlyHeap&) = delete;
//};
//int main()
//{
//	OnlyHeap* ptr=OnlyHeap::CreateObject();
//	delete ptr;
//	OnlyHeap obj(*ptr);
//	return 0;
//}


//#include <iostream>
//using namespace std;
////只能在栈上创建对象
//class OnlyStack
//{
//public:
//	static OnlyStack CreateObject()
//	{
//		return OnlyStack();
//	}
//
//	// 禁掉operator new可以把下面用new 调用拷贝构造申请对象给禁掉
//	void* operator new(size_t) = delete;
//	void operator delete(void*) = delete;
//private:
//	OnlyStack()
//	{	}
//};
//int main()
//{
//	OnlyStack st=OnlyStack::CreateObject();
//
//	//OnlyStack* ptr1 = new OnlyStack;
//	//OnlyStack* ptr2= new OnlyStack(st);
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//class Base final
//{
//	Base()
//	{
//
//	}
//};
//
//
//class Derive :public Base
//{
//
//};
//
//int main()
//{
//	Derive d;
//	return 0;
//}

//#include <iostream>
//#include <vector>
//#include <string>
//#include <thread>
//#include <mutex>
//using namespace std;
////饿汉模式
//class Singleton
//{
//public:
//	//使用static函数来返回能创建的唯一对象
//	static Singleton* GetInstance()
//	{
//		return _instance;
//	}
//	
//	//要保证线程安全
//	void Add(const string& d)
//	{
//		mtx.lock();
//		_data.push_back(d);
//		mtx.unlock();
//	}
//
//	//读数据也会有线程安全问题
//	void Print()
//	{
//		int cnt = 0;
//		mtx.lock();
//		for (auto& e : _data)
//		{
//			cnt++;
//			cout << e << endl;
//		}
//		mtx.unlock();
//		cout << "cnt=" << cnt << endl;
//	}
//
//private:
//	Singleton()//将构造函数隐藏起来，保证不能随意创建对象
//	{}
//
//	//⭐⭐⭐这边要注意，需要把它给禁用掉，否则，可以通过*GetInstance来进行拷贝构造
//	Singleton(const Singleton& sg) = delete;
//	Singleton& operator=(const Singleton& sg) = delete;//保险起见也delete
//
//
//private:
//	vector<string> _data;
//	//对象也要是static，这样才能让GetInstance返回
//	static Singleton* _instance;
//	mutex mtx;//保证在输入数据时的安全
//};
//
//Singleton* Singleton::_instance = new Singleton;
//
//
//int main()
//{
//		srand((unsigned)time(nullptr));
//	int n = 30;
//	thread t1([n] {
//		for (int i = 0; i < n; i++)
//			Singleton::GetInstance()->Add("thread t1-" + to_string(rand() % 100 + 1));
//		});
//
//	thread t2([n] {
//		for (int i = 0; i < n; i++)
//			Singleton::GetInstance()->Add("thread t2-" + to_string(rand() % 100 + 1));
//		});
//
//	t1.join();
//	t2.join();
//
//	Singleton::GetInstance()->Print();
//	return 0;
//}

////多线程测试
//void ThreadTest()
//{
//	Singleton* ptr = Singleton::GetInstance();
//	for (int i = 0; i < 20; i++)
//	{
//		ptr->Add("I am thread,the num is " + to_string(i));
//	}
//}
//int main()
//{
//	Singleton* ptr=Singleton::GetInstance();
//	//创建线程测试
//	thread t1(ThreadTest);
//	thread t2(ThreadTest);
//
//	t1.join();
//	t2.join();
//	//查看结果是否正常
//	ptr->Print();
//
//	return 0;
//}



//#include <iostream>
//#include <vector>
//#include <string>
//#include <thread>
//#include <mutex>
//#include <ctime>
//#include <cstdlib>
//using namespace std;
////懒汉模式
//class Singleton
//{
//public:
//	static Singleton* GetInstance()
//	{
//
//		if (_instance == nullptr)//双重检测
//		{
//			//这边加上锁后，每次有线程进来时都会上锁，然后解锁，再返回；即使_instance
//			//不为nullptr，这样效率就会大大降低，因此我们需要可以双重检测
//			_mtx.lock();
//			if (_instance == nullptr)
//			{
//				_instance = new Singleton;
//			}
//			_mtx.unlock();
//		}
//		return _instance;
//
//	}
//
//	//要注意线程安全
//	void Add(const string& str)
//	{
//		_mtx.lock();
//		_data.push_back(str);
//		_mtx.unlock();
//	}
//
//	//要注意线程安全
//	void Print()
//	{
//		int cnt = 0;//计算数量
//		_mtx.lock();
//		for (auto& e : _data)
//		{
//			cnt++;
//			cout << e << endl;
//		}
//		_mtx.unlock();
//		cout <<"cnt="<< cnt << endl;
//	}
//
//	~Singleton()
//	{
//		//析构函数可以用来做一些最后的写入工作
//	}
//
//	//garbage collection--垃圾回收
//	struct GC
//	{
//		~GC()
//		{
//			DelInstance();
//		}
//	};
//
//	//用来回收释放单例，必须使用static，这样才能保证在程序结束的时候，能够调用_gc的析构
//	//不使用static的话，就是作为单例对象一部分，而单例还需要等待释放，而GC就是为了释放单例，就出现了蛋生鸡鸡生蛋问题
//	static GC _gc;
//	
//	static void DelInstance()//这边也要保证是static，不然回收类无法使用
//	{
//		_mtx.lock();//这个也要保证线程安全
//		if (_instance)
//		{
//			delete _instance;
//			_instance = nullptr;
//		}
//		_mtx.unlock();
//	}
//
//
//private:
//	Singleton()
//	{}
//	//⭐⭐⭐这边要注意，需要把它给禁用掉，否则，可以通过*GetInstance来进行拷贝构造
//	Singleton(const Singleton& sg) = delete;
//	Singleton& operator=(const Singleton& sg) = delete;//保险起见也delete
// 
// 
//private:
//	static Singleton* _instance;//用来接受创建的唯一对象
//	vector<string> _data;//存数据
//	//也得设为static,不然GetInstance中无法使用
//	static mutex _mtx;
//};
//
////懒汉是在使用时才创建，所以说这边先初始化为nullptr
//Singleton* Singleton::_instance = nullptr;
//mutex Singleton::_mtx;//表示初始化锁
//int main()
//{
//	srand((unsigned)time(nullptr));
//	int n = 30;
//	thread t1([n] {
//		for (int i = 0; i < n; i++)
//			Singleton::GetInstance()->Add("thread t1-" + to_string(rand() % 100 + 1));
//		});
//
//	thread t2([n] {
//		for (int i = 0; i < n; i++)
//			Singleton::GetInstance()->Add("thread t2-" + to_string(rand() % 100 + 1));
//		});
//
//	t1.join();
//	t2.join();
//
//	Singleton::GetInstance()->Print();
//	return 0;
//}


//#include <iostream>
//#include <map>
//#include <set>
//#include <string>
//using namespace std;
//int main()
//{
//	map<string, string> m;
//	m.insert(make_pair("pg", "apple"));
//	cout << m["pg"] << endl;
//
//
//
//	return 0;
//}


//#include <iostream>
//using namespace std;
//int main()
//{
//	//隐式类型转换
//	double d = 11.1;
//	int x = d;
//
//	//隐式类型转换需要两个类型的意义相同
//	int* ptr = &x;
//	//int y = ptr;//error
//
//	//显式类型转换（强转）
//	int y = (int)ptr;
//
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//int main()
//{
//	int x = 10;
//	double d = static_cast<double>(x);
//	cout << d << endl;
//
//	float f = 11.1f;
//	int y = static_cast<int>(f);
//	cout << y<< endl;
//	return 0;
//}

//#include <iostream>
//using namespace std;
//int main()
//{
//	int x = 10;
//	int* ptr = &x;
//	printf("%x\n", ptr);
//	int y = reinterpret_cast<int>(ptr);
//	printf("%x\n",y);
//
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//int main()
//{
//	volatile const int x = 10;
//	volatile const int* ptr = &x;//用const修饰了ptr指向的值，因此它指向的值不能修改
//
//	int* ptr1 = const_cast<int*>(ptr);//这边通过const_cast删除了const属性，使他可以赋值
//
//	*ptr1 = 100;
//
//	cout << x << endl;
//	cout << *ptr1<< endl;
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//class Base
//{
//public:
//	virtual void Test()//基类没有虚函数就不能使用dynamic_cast,无法编译
//	{
//	}
//};
//
//class Derive:public Base
//{
//public:
//};
//
//void Func(Base* b)
//{
//	Derive* ret= dynamic_cast<Derive*>(b);
//	cout << ret << endl;
//}
//
//void Func1(Base& b)
//{
//	Derive& ret = dynamic_cast<Derive&>(b);
//}
//
//int main()
//{
//	Derive d;
//	Func(&d);
//
//	Derive d1;
//	Func1(d1);
//
//	Base b;
//	Func(&b);//无法转换成功
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//int main()
//{
//	cout << "hello world" << endl;
//	cerr << "hello world" << endl;
//	clog << "hello world" << endl;
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//int main()
//{
//	int x;
//	while (cin >> x)//调用operator bool()const
//	{
//		//
//	}
//	cout << x << endl;
//
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//struct Test
//{
//	 explicit operator bool()//注意写法，没有返回值
//	{
//		if (_x)
//		{
//			return true;
//		}
//		else
//		{
//			return false;
//		}
//	}
//	int _x;
//};
//
//int main()
//{
//	Test t;
//	t._x = 1;
//	//bool b = t;//error
//	bool b = (bool)t;
//	cout << b << endl;
//	return 0;
//}


//#include <iostream>
//#include <fstream>
//#include <string>
//using namespace std;
//struct Person
//{
//	Person(const string& name="", const string& birth="", char sex=0)
//		:_name(name),_birth(birth),_sex(sex)
//	{}
//	string _name;
//	string _birth;
//	char _sex;
//};
//
//struct Manager
//{
//	Manager(const string& filename)
//		:_filename(filename)
//	{}
//
//	//文本文件
//	void WriteText(const Person& p)
//	{
//		ofstream fs(_filename.c_str());
//		fs << p._birth <<" "<< p._name <<" "<<p._sex;
//		fs.close();
//	}
//
//	void ReadText(Person& p)
//	{
//		ifstream fs(_filename.c_str());
//		fs >> p._birth >> p._name >> p._sex;
//	}
//	//二进制文件
//	void WriteBin(const Person& p, int& namelen,int& birthlen)
//	{
//		ofstream fs(_filename.c_str(), ofstream::binary | ofstream::out);
//		//需要将Perosn中string对象的字符串长度传出去
//		fs.write(p._name.c_str(),namelen=strlen(p._name.c_str())+1);//+1是还有'\0'
//		fs.write(p._birth.c_str(),birthlen=strlen(p._birth.c_str())+1);
//		fs.write(&p._sex, sizeof(p._sex));
//		fs.close();
//	}
//
//	void ReadBin(Person& p,int& namelen,int& birthlen)
//	{
//		ifstream fs(_filename.c_str(), ofstream::binary | ofstream::in);
//		p._birth.resize(birthlen - 1);
//		p._name.resize(namelen - 1);//提前扩大字符串长度，不能使用reserve，reserve只扩大容量
//		fs.read((char*)p._name.c_str(),namelen);//必须强转，因为返回的是const char*
//		fs.read((char*)p._birth.c_str(),birthlen);
//		fs.read(&p._sex, sizeof(p._sex));
//		fs.close();
//	}
//
//private:
//	string _filename;
//};
//
//
//int main()
//{
//	Person wp1("lnb","2000/1/1",'M');
//	Manager m1("test.txt");
//	m1.WriteText(wp1);
//	Person rp1;
//	m1.ReadText(rp1);
//	cout << rp1._name <<" "<<rp1._birth <<" "<<rp1._sex << endl;
//
//	
//	Person wp2("lisa", "1990/2/12", 'F');
//	Manager m2("test.bin");
//	int namelen = 0, birthlen = 0;
//	m2.WriteBin(wp2,namelen,birthlen);
//	Person rp2;
//	m2.ReadBin(rp2, namelen, birthlen);
//	cout << rp2._name << " " << rp2._birth << " " << rp2._sex << endl;
//	return 0;
//}

//#include <iostream>
//#include <fstream>
//#include <string>
//using namespace std;
//struct Person
//{
//	char name[20];
//	char sex;
//};
//
//struct Manager
//{
//	Manager(const string& filename)
//		:_filename(filename)
//	{}
//
//	//文本文件
//	void WriteText(const Person& p)
//	{
//		ofstream fs(_filename.c_str());
//		fs << p.name << " " << p.sex;
//		fs.close();
//	}
//
//	void ReadText(Person& p)
//	{
//		ifstream fs(_filename.c_str());
//		fs >> p.name >> p.sex;
//		fs.close();
//	}
//	//二进制文件
//	void WriteBin(const Person& p)
//	{
//		ofstream fs(_filename.c_str(), ofstream::binary | ofstream::out);
//		fs.write((char*)&p, sizeof(p));
//		fs.close();
//	}
//
//	void ReadBin(Person& p)
//	{
//		ifstream fs(_filename.c_str(), ofstream::binary | ofstream::in);
//		fs.read((char*)&p, sizeof(p));
//		fs.close();
//	}
//
//private:
//	string _filename;
//};
//
//
//int main()
//{
//	Person wp1= { "lnb",'M'};
//	Manager m1("test.txt");
//	m1.WriteText(wp1);
//	Person rp1;
//	m1.ReadText(rp1);
//	cout << rp1.name << " " << rp1.sex << endl;
//
//	Person wp2 = { "lisa",'F' };
//	Manager m2("test.bin");
//	m2.WriteBin(wp2);
//	Person rp2;
//	m2.ReadBin(rp2);
//	cout << rp2.name << " " << rp2.sex << endl;
//	return 0;
//}

//#include <iostream>
//#include <sstream>
//using namespace std;
//int main()
//{
//	stringstream ss;
//	ss << 10;
//	ss << 19.1;
//	ss << "helloworld";
//	
//
//	char str[30];
//	ss >>str;
//	cout << str << endl;
//
//
//	return 0;
//}

//#include <stdio.h>
//#include <string.h>
//int main()
//{
//	int x = 10;
//	float f = 19.1f;
//	char str[30];
//	sprintf(str, "int:%d,float:%.2f", x, f);
//	printf("%s", str);
//
//	return 0;
//}


//#include <iostream>
//#include <sstream>
//using namespace std;
//int main()
//{
//	int x = 10;
//	float f = 19.1f;
//	stringstream ss;
//	string str;
//	ss << "int:" << x << ",float:" << f;
//	ss >> str;
//	cout << str << endl;
//
//	ss.clear();//需要进行把状态清空掉
//	str.clear();//清空str
//	ss << "helloworld";
//	ss >> str;//发现无法输入到str中
//	cout << str << endl;
//	return 0;
//}

//#include <sstream>
//#include <iostream>
//using namespace std;
//int main()
//{
//	int a = 10;
//	float f = 19.1f;
//	stringstream ss;
//	ss << a << f;
//	string str=ss.str();//获取底层的字符串
//	cout << str << endl;
//	//将底层string对象设置为" ",否则多次转换后，会将结果全部积累在底层string对象中，
//	//返回值是stringstream中管理的string类型
//	ss.str("");
//	str.clear();
//	ss >> str;
//	cout << str << endl;
//	return 0;
//}


//#include <iostream>
//#include <sstream>
//using namespace std;
//int main()
//{
//	int x = 10;
//	float f = 19.1f;
//	stringstream ss;
//	string str;
//	ss << "int:" << x << ",float:" << f;
//	ss >> str;
//	cout << str << endl;
//
//	ss.clear();//需要进行把状态清空掉
//	str.clear();//清空str
//	ss << "helloworld";
//
//	str = ss.str();//不进行清空的情况
//	//虽然使用正常的>>流提取不会出现直接提取过的数据，但是底层的string对象中，之前的字符串还在
//	cout << str << endl;
//	return 0;
//}


//#include <iostream>
//#include <sstream>
//using namespace std;
//struct Person
//{
//	string name;
//	string birth;
//	int age;
//};
//int main()
//{
//	// 结构信息序列化为字符串
//	Person p = { "lnb","2000/1/1",19 };
//	ostringstream os;
//	os << p.name << " " << p.birth << " " << p.age;
//	cout << p.name << " " << p.birth << " " << p.age << endl;
//	string info=os.str();
//	//字符串解析为结构信息
//	Person rp;
//	istringstream is(info);
//	is >> rp.name >> rp.birth >> rp.age;
//	cout << rp.name << " " << rp.birth << " " << rp.age << endl;
//
//	return 0;
//}

#include "mystring.hpp"
int main()
{
	bit::test_string10();

	return 0;
}